package com.szgz.platform.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.szgz.platform.exception.BusinessException;
import com.szgz.platform.mapper.TaskStepMapper;
import com.szgz.platform.model.TaskStep;
import com.szgz.platform.service.TaskStepService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 任务步骤服务实现类
 */
@Slf4j
@Service
public class TaskStepServiceImpl extends ServiceImpl<TaskStepMapper, TaskStep> implements TaskStepService {

    @Override
    public IPage<TaskStep> getStepsByTaskId(Page<TaskStep> page, Long taskId, String status) {
        if (taskId == null) {
            throw new BusinessException("任务ID不能为空");
        }
        
        LambdaQueryWrapper<TaskStep> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TaskStep::getTaskId, taskId)
               .eq(StringUtils.hasText(status), TaskStep::getStatus, status)
               .orderByAsc(TaskStep::getStepOrder);
        
        return baseMapper.selectStepsByTaskId(page, taskId, status);
    }

    @Override
    public List<TaskStep> getStepsTreeByTaskId(Long taskId, String status) {
        if (taskId == null) {
            throw new BusinessException("任务ID不能为空");
        }
        
        // 查询所有步骤
        List<TaskStep> allSteps = baseMapper.selectStepsTreeByTaskId(taskId, status);
        
        // 构建树形结构
        return buildStepTree(allSteps);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createTaskStep(TaskStep taskStep) {
        if (taskStep == null || taskStep.getTaskId() == null) {
            throw new BusinessException("步骤信息不完整");
        }
        
        // 设置默认值
        if (taskStep.getStepOrder() == null) {
            taskStep.setStepOrder(getNextStepOrder(taskStep.getTaskId(), taskStep.getParentStepId()));
        }
        if (taskStep.getStatus() == null) {
            taskStep.setStatus(TaskStep.StepStatus.ACTIVE.getCode());
        }
        if (taskStep.getIsRequired() == null) {
            taskStep.setIsRequired(true);
        }
        if (taskStep.getIsVisible() == null) {
            taskStep.setIsVisible(true);
        }
        if (taskStep.getCanSkip() == null) {
            taskStep.setCanSkip(false);
        }
        
        return save(taskStep);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateTaskStep(TaskStep taskStep) {
        if (taskStep == null || taskStep.getId() == null) {
            throw new BusinessException("步骤信息不完整");
        }
        
        // 检查步骤是否存在
        TaskStep existingStep = getById(taskStep.getId());
        if (existingStep == null) {
            throw new BusinessException("步骤不存在");
        }
        
        return updateById(taskStep);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteTaskStep(Long stepId) {
        if (stepId == null) {
            throw new BusinessException("步骤ID不能为空");
        }
        
        // 检查是否有子步骤
        List<TaskStep> children = getChildrenByParentId(stepId, null);
        if (!children.isEmpty()) {
            throw new BusinessException("该步骤下有子步骤，无法删除");
        }
        
        // 检查是否有其他步骤依赖此步骤
        List<TaskStep> dependents = getDependentsByStepId(stepId);
        if (!dependents.isEmpty()) {
            throw new BusinessException("有其他步骤依赖此步骤，无法删除");
        }
        
        return removeById(stepId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchDeleteTaskSteps(List<Long> stepIds) {
        if (stepIds == null || stepIds.isEmpty()) {
            throw new BusinessException("步骤ID列表不能为空");
        }
        
        // 检查是否有子步骤或依赖关系
        for (Long stepId : stepIds) {
            List<TaskStep> children = getChildrenByParentId(stepId, null);
            List<TaskStep> dependents = getDependentsByStepId(stepId);
            
            if (!children.isEmpty() || !dependents.isEmpty()) {
                throw new BusinessException("步骤ID " + stepId + " 无法删除，存在子步骤或依赖关系");
            }
        }
        
        return removeByIds(stepIds);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateStepOrder(Long stepId, Integer newOrder) {
        if (stepId == null || newOrder == null) {
            throw new BusinessException("步骤ID和新顺序不能为空");
        }
        
        return baseMapper.updateStepOrder(stepId, newOrder) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchUpdateStepOrders(Map<Long, Integer> stepOrders) {
        if (stepOrders == null || stepOrders.isEmpty()) {
            throw new BusinessException("步骤顺序映射不能为空");
        }
        
        for (Map.Entry<Long, Integer> entry : stepOrders.entrySet()) {
            if (!updateStepOrder(entry.getKey(), entry.getValue())) {
                throw new BusinessException("更新步骤顺序失败");
            }
        }
        
        return true;
    }

    @Override
    public List<TaskStep> getChildrenByParentId(Long parentStepId, String status) {
        if (parentStepId == null) {
            return new ArrayList<>();
        }
        
        LambdaQueryWrapper<TaskStep> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TaskStep::getParentStepId, parentStepId)
               .eq(StringUtils.hasText(status), TaskStep::getStatus, status)
               .orderByAsc(TaskStep::getStepOrder);
        
        return list(wrapper);
    }

    @Override
    public TaskStep getParentByStepId(Long stepId) {
        if (stepId == null) {
            return null;
        }
        
        TaskStep step = getById(stepId);
        if (step == null || step.getParentStepId() == null) {
            return null;
        }
        
        return getById(step.getParentStepId());
    }

    @Override
    public List<TaskStep> getDependenciesByStepId(Long stepId) {
        if (stepId == null) {
            return new ArrayList<>();
        }
        
        return baseMapper.selectDependenciesByStepId(stepId);
    }

    @Override
    public List<TaskStep> getDependentsByStepId(Long stepId) {
        if (stepId == null) {
            return new ArrayList<>();
        }
        
        return baseMapper.selectDependentsByStepId(stepId);
    }

    @Override
    public List<TaskStep> getStepsByType(Long taskId, String stepType, String status) {
        if (taskId == null) {
            return new ArrayList<>();
        }
        
        return baseMapper.selectStepsByType(taskId, stepType, status);
    }

    @Override
    public int countStepsByTaskId(Long taskId, String status) {
        if (taskId == null) {
            return 0;
        }
        
        return baseMapper.countStepsByTaskId(taskId, status);
    }

    @Override
    public List<TaskStep> getAccessibleSteps(Long taskId, Long userId, String status) {
        if (taskId == null || userId == null) {
            return new ArrayList<>();
        }
        
        return baseMapper.selectAccessibleSteps(taskId, userId, status);
    }

    @Override
    public boolean validateStepDependencies(Long stepId) {
        if (stepId == null) {
            return false;
        }
        
        List<TaskStep> dependencies = getDependenciesByStepId(stepId);
        if (dependencies.isEmpty()) {
            return true;
        }
        
        // 这里可以添加具体的依赖验证逻辑
        // 例如检查依赖步骤是否已完成等
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean copyTaskSteps(Long sourceTaskId, Long targetTaskId) {
        if (sourceTaskId == null || targetTaskId == null) {
            throw new BusinessException("源任务ID和目标任务ID不能为空");
        }
        
        // 查询源任务的所有步骤
        List<TaskStep> sourceSteps = getStepsTreeByTaskId(sourceTaskId, TaskStep.StepStatus.ACTIVE.getCode());
        
        // 复制步骤到新任务
        for (TaskStep sourceStep : sourceSteps) {
            TaskStep newStep = new TaskStep();
            newStep.setTaskId(targetTaskId);
            newStep.setParentStepId(null); // 暂时设为null，后续处理
            newStep.setStepOrder(sourceStep.getStepOrder());
            newStep.setStepType(sourceStep.getStepType());
            newStep.setTitle(sourceStep.getTitle());
            newStep.setDescription(sourceStep.getDescription());
            newStep.setContent(sourceStep.getContent());
            newStep.setRequirements(sourceStep.getRequirements());
            newStep.setEstimatedTime(sourceStep.getEstimatedTime());
            newStep.setMaxScore(sourceStep.getMaxScore());
            newStep.setPassScore(sourceStep.getPassScore());
            newStep.setIsRequired(sourceStep.getIsRequired());
            newStep.setIsVisible(sourceStep.getIsVisible());
            newStep.setCanSkip(sourceStep.getCanSkip());
            newStep.setDependencies(sourceStep.getDependencies());
            newStep.setResources(sourceStep.getResources());
            newStep.setMetadata(sourceStep.getMetadata());
            newStep.setStatus(TaskStep.StepStatus.ACTIVE.getCode());
            
            save(newStep);
        }
        
        return true;
    }

    @Override
    public List<TaskStep> getStepPath(Long stepId) {
        if (stepId == null) {
            return new ArrayList<>();
        }
        
        List<TaskStep> path = new ArrayList<>();
        TaskStep currentStep = getById(stepId);
        
        while (currentStep != null) {
            path.add(0, currentStep); // 添加到开头，保持从根到叶的顺序
            if (currentStep.getParentStepId() != null) {
                currentStep = getById(currentStep.getParentStepId());
            } else {
                break;
            }
        }
        
        return path;
    }

    @Override
    public boolean isStepVisible(Long stepId, Long userId) {
        if (stepId == null || userId == null) {
            return false;
        }
        
        TaskStep step = getById(stepId);
        if (step == null) {
            return false;
        }
        
        // 检查步骤是否可见
        if (!step.getIsVisible()) {
            return false;
        }
        
        // 这里可以添加更多的可见性检查逻辑
        // 例如检查用户权限、步骤状态等
        
        return true;
    }

    @Override
    public boolean isStepSkippable(Long stepId, Long userId) {
        if (stepId == null || userId == null) {
            return false;
        }
        
        TaskStep step = getById(stepId);
        if (step == null) {
            return false;
        }
        
        // 检查步骤是否可跳过
        if (!step.getCanSkip()) {
            return false;
        }
        
        // 这里可以添加更多的跳过检查逻辑
        // 例如检查依赖关系、用户权限等
        
        return true;
    }

    /**
     * 构建步骤树形结构
     */
    private List<TaskStep> buildStepTree(List<TaskStep> allSteps) {
        if (allSteps == null || allSteps.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 创建ID到步骤的映射
        Map<Long, TaskStep> stepMap = allSteps.stream()
                .collect(Collectors.toMap(TaskStep::getId, step -> step));
        
        // 构建树形结构
        List<TaskStep> rootSteps = new ArrayList<>();
        
        for (TaskStep step : allSteps) {
            if (step.getParentStepId() == null) {
                // 根步骤
                rootSteps.add(step);
            } else {
                // 子步骤
                TaskStep parent = stepMap.get(step.getParentStepId());
                if (parent != null) {
                    if (parent.getChildren() == null) {
                        parent.setChildren(new ArrayList<>());
                    }
                    parent.getChildren().add(step);
                    step.setParent(parent);
                }
            }
        }
        
        // 递归排序子步骤
        for (TaskStep rootStep : rootSteps) {
            sortStepChildren(rootStep);
        }
        
        return rootSteps;
    }

    /**
     * 递归排序子步骤
     */
    private void sortStepChildren(TaskStep step) {
        if (step.getChildren() != null && !step.getChildren().isEmpty()) {
            step.getChildren().sort(Comparator.comparing(TaskStep::getStepOrder));
            for (TaskStep child : step.getChildren()) {
                sortStepChildren(child);
            }
        }
    }

    /**
     * 获取下一个步骤顺序
     */
    private Integer getNextStepOrder(Long taskId, Long parentStepId) {
        LambdaQueryWrapper<TaskStep> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TaskStep::getTaskId, taskId)
               .eq(TaskStep::getParentStepId, parentStepId)
               .orderByDesc(TaskStep::getStepOrder)
               .last("LIMIT 1");
        
        TaskStep lastStep = getOne(wrapper);
        return lastStep != null ? lastStep.getStepOrder() + 1 : 1;
    }
} 